﻿using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using System.ComponentModel;
using FreeSql.DataAnnotations;
using D.UtilCore;
using CozeDomain.IServices;
using D.UtilCore.Dtos;
using D.UtilCore.Filters;
using D.Tool.CodeBuild.Models;
using D.Util.UtilCompression;

namespace CozeWebApi
{
    [Route("/api/[controller]/[action]")]
    public class SysCodeBuilderController : BaseApiController
    {

        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly ISysCodeBuilderService _sysBuilderService;
        /// <summary>
        /// 构造注入
        /// </summary>
        public SysCodeBuilderController(IWebHostEnvironment hostingEnvironment, ISysCodeBuilderService sysBuilderService)
        {
            _hostingEnvironment = hostingEnvironment;
            _sysBuilderService = sysBuilderService;
        }

        /// <summary>
        /// 获取当前后端所有数据库
        /// </summary>
        /// <returns></returns>
        [HttpGet, TypeFilter(typeof(ExtActionFilterAttribute))]
        public ApiResult<IEnumerable<string>> GetDbList()
        {
            var dbs = _sysBuilderService.GetDbList();
            return dbs;
        }

        /// <summary>
        /// 获取某个表字段列表
        /// </summary>
        /// <param name="dbName">表名</param>
        /// <returns></returns>
        [HttpGet("{dbName}"), TypeFilter(typeof(ExtActionFilterAttribute))]
        public ApiResult<IEnumerable<TablesInput>> GetTableList(string dbName)
        {
            var tables = _sysBuilderService.GetTableList(dbName);
            var list = tables.Data.Select(m => new TablesInput()
            {
                Id = m.Id,
                Comment = m.Comment,
                Name = m.Name,
                Columns = m.Columns.Select(c => new ColumnsInput()
                {
                    ParentId = m.Id,
                    Coment = c.Coment,
                    FiledType = c.FiledType,
                    DbTypeTextFull = c.DbTypeTextFull,
                    DefaultValue = c.DefaultValue,
                    IsIdentity = c.IsIdentity,
                    IsNullable = c.IsNullable,
                    IsRequired = c.IsNullable,
                    IsPrimary = c.IsPrimary,
                    MaxLength = c.MaxLength,
                    Name = c.Name,
                }).ToList()
            });

            return new ApiResult<IEnumerable<TablesInput>>() { Code = StatusCodeEnum.OK, Data = list };
        }

        /// <summary>
        /// 获取所有实体
        /// </summary>
        /// <param name="projectName">头部</param>
        /// <returns></returns>
        [HttpGet("{projectName}"), TypeFilter(typeof(ExtActionFilterAttribute))]
        public ApiResult<IEnumerable<TablesInput>> GetModelList(string projectName)
        {
            if (string.IsNullOrEmpty(projectName))
            {
                return new ApiResult<IEnumerable<TablesInput>>();
            }
            var list = new List<TablesInput>();
            //加载指定的程序集
            //var p = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            var path = Path.Combine(AppContext.BaseDirectory, projectName + ".dll");
            var asm = Assembly.LoadFile(path);

            //获取程序集中的所有类型列表
            var alltype = asm.GetTypes().Where(m => m.Namespace == projectName + ".Entities");
            foreach (Type m in alltype)
            {
                var tableInput = new TablesInput()
                {
                    Id = m.Name,
                    Comment = (m.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute)?.Description,
                    Name = m.Name,
                };

                tableInput.Columns = new List<ColumnsInput>();

                var properties = m.GetProperties();
                foreach (PropertyInfo c in properties)
                {
                    var attr = c.GetCustomAttribute(typeof(ColumnAttribute), true) as ColumnAttribute;

                    //判断是否为可空泛型
                    var column = new ColumnsInput()
                    {
                        //ParentId = m.Id,
                        Coment = (c.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute)?.Description,
                        FiledType = c.PropertyType.FullName,
                        DbTypeTextFull = attr.DbType,
                        //DefaultValue = c.GetValue(m,null)?.ToString(),
                        IsIdentity = attr != null ? attr.IsIdentity : false,
                        IsNullable = attr != null ? attr.IsNullable : true,
                        IsRequired = attr != null ? !attr.IsNullable : false,
                        IsPrimary = attr != null ? attr.IsPrimary : true,
                        //MaxLength = c.PropertyType.FullName == "System.String" ? attr.StringLength : attr.Precision,
                        Name = c.Name
                    };

                    //判断是否为可空值
                    //var d = Nullable.GetUnderlyingType(c.PropertyType.GetType());
                    //var s = c.PropertyType.FullName.Contains(typeof(Nullable).ToString());
                    if (c.PropertyType.IsGenericType && c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        column.FiledType = c.PropertyType.GetGenericArguments()[0].FullName;
                    }

                    tableInput.Columns.Add(column);
                }

                list.Add(tableInput);
            }

            return new ApiResult<IEnumerable<TablesInput>>() { Code = StatusCodeEnum.OK, Data = list };
        }

        /// <summary>
        /// 生成项目
        /// </summary>
        /// <param name="buildModuleInput"></param>
        /// <returns></returns>
        [HttpPost, TypeFilter(typeof(ExtActionFilterAttribute))]
        public ApiResult<ResponseCodeBild> Create([FromBody] BuildModuleInput buildModuleInput)
        {
            var result = new ApiResult<ResponseCodeBild>() { Code = StatusCodeEnum.OK };

            if (string.IsNullOrEmpty(buildModuleInput.ProjectName) || buildModuleInput.Tables.Count == 0)
            {
                result.Code = StatusCodeEnum.Waring;
                result.Msg = "相关参数不可为空";
                return result;
            }

            // 后台根路径
            var rootPath = AppDomain.CurrentDomain.BaseDirectory;

            // 生成代码
            D.Tool.CodeBuild.Startup.AddCodeBuild(buildModuleInput, rootPath);

            // 压缩包名称
            string zipFileName = buildModuleInput.ProjectName + DateTime.Now.ToString("yyyyMMddHHmmss") + ".zip";

            // 删除已经存在的压缩包
            string zipFileAllPath = rootPath + zipFileName;
            if (System.IO.File.Exists(zipFileAllPath))
            {
                System.IO.File.Delete(zipFileAllPath);
            }

            // 生成新的压缩包
            ZipUtil.ZipCompress(rootPath, zipFileName);

            // 删除生成的其他文件
            ZipUtil.DeleteDirectory(zipFileAllPath);

            // 返回压缩包路径地址
            result.Data = new ResponseCodeBild() { Url = zipFileAllPath, FileName = zipFileName };
            return result;
        }
    }
}
